<?php


namespace CymTools\Im\Account;


use CymTools\Im\Support\Host;
use CymTools\Kernel\ServiceClient;
use CymTools\Kernel\Support\Str;
use Psr\Http\Message\ResponseInterface;
use \CymTools\Im\Support\TLSSigAPIv2;
use \GuzzleHttp\Client as Http;

class Client extends ServiceClient
{
    // 默认管理员账号ID
    private $identifier = 'administrator';

    // 腾讯IM分配的SDK APPID
    private $appid;

    //腾讯IM分配的SDK SECRET
    private $secret;

    // HTTP请求
    private $http;

    /**
     * @var TLSSigAPIv2
     */
    private $TLSSignAPI;



    public function __construct($app)
    {
        parent::__construct($app);
        $this->http = new Http(['verify'=>false]);
        $this->TLSSignAPI = new TLSSigAPIv2($this->config->accessKeyId, $this->config->accessKeySecret);
    }

    /**
     * 导入单个账号
     * @param $identifier string 账号用户名 通常为用户ID
     * @param $nickname string 用户昵称
     * @param $faceUrl string 用户头像URL
     * @throws \Exception
     */
    public function accountImport(string $identifier, string $nickname='', string $faceUrl=''): ResponseInterface
    {
        $url = $this->getUrlParameter(Host::ACCOUNT_IMPORT_URL);
        $data['Identifier'] = $identifier;
        if (!empty($nickname)){
            $data['Nick'] = $nickname;
        }
        if (!empty($faceUrl)){
            $data['FaceUrl'] = $faceUrl;
        }
        $data = ['Identifier'=>$identifier, 'Nick'=>$nickname, 'FaceUrl'=>$faceUrl];
        return $this->http->post($url, ['json'=>$data]);
    }



    /**
     * 检测账户是否导入
     * @param array $identifiers
     * @return \Psr\Http\Message\ResponseInterface
     * @throws \Exception
     */
    public function accountCheck(array $identifiers): ResponseInterface
    {
        $url = $this->getUrlParameter(Host::ACCOUNT_CHECK_URL);
        $userIds = [];
        foreach ($identifiers as $identifier){
            $userIds[]['UserID'] = $identifier;
        }
        return $this->http->post($url, ['json'=>['CheckItem'=>$userIds] ]);
    }


    /**
     * 设置资料URL
     * @param string $fromAccount 需要设置该 UserID 的资料
     * @param array $profileItem 待设置的用户的资料对象数组，数组中每一个对象都包含了 Tag 和 Value
     * @return ResponseInterface
     * @throws \Exception
     */
    public function portraitSet(string $fromAccount, array $profileItem): ResponseInterface
    {
        $url = $this->getUrlParameter(Host::PORTRAIT_SET_URL);
        return $this->http->post($url, ['json'=>['From_Account'=>$fromAccount, 'ProfileItem'=>$profileItem] ]);
    }

    /**
     * 拉入黑名单
     * @param $formAccount
     * @param $toAccount
     * @return ResponseInterface
     * @throws \Exception
     */
    public function blackListAdd($formAccount, $toAccount): ResponseInterface
    {
        $url = $this->getUrlParameter(Host::BLACK_LIST_ADD_URL);
        $toData = [];
        if (is_string($toAccount) ){
            $toData[] = $toAccount;
        }else if (is_array($toAccount)){
            $toData = $toAccount;
        }else{
            die("无效的数据类型");
        }
        return $this->http->post($url, ['json'=>['From_Account'=>$formAccount, 'To_Account'=>$toData]]);
    }

    /**
     * 删除黑名单接口
     * @param $formAccount
     * @param $toAccount
     * @return ResponseInterface
     * @throws \Exception
     */
    public function blackListDelete($formAccount, $toAccount): ResponseInterface
    {
        $url = $this->getUrlParameter(Host::BLACK_LIST_DELETE_URL);
        $toData = [];
        if (is_string($toAccount) ){
            $toData[] = $toAccount;
        }else if (is_array($toAccount)){
            $toData = $toAccount;
        }else{
            die("无效的数据类型");
        }
        return $this->http->post($url, ['json'=>['From_Account'=>$formAccount, 'To_Account'=>$toData]]);
    }

    /**
     * 校验是否存在黑名单
     * @param $fromAccount
     * @param $toAccount
     * @param string $check_type
     * @return ResponseInterface
     * @throws \Exception
     */
    public function checkBlackList($fromAccount, $toAccount, $check_type = 'BlackCheckResult_Type_Both')
    {
        $url = $this->getUrlParameter(Host::BLACK_LIST_CHECK_URL);
        $toData = [];
        if (is_string($toAccount) ){
            $toData[] = $toAccount;
        }else if (is_array($toAccount)){
            $toData = $toAccount;
        }else{
            die("无效的数据类型");
        }
        return $this->http->post($url, ['json'=>['From_Account'=>$fromAccount, 'To_Account'=>$toData, 'CheckType'=>$check_type]]);
    }

    /**
     * 获取黑名单列表
     * @param $formAccount
     * @param $index
     * @param $limit
     * @param int $lastSeq
     * @return ResponseInterface
     * @throws \Exception
     */
    public function getBlackList($formAccount, $index, $limit, $lastSeq = 0)
    {
        $url = $this->getUrlParameter(Host::GET_BLACK_LIST_URL);
        return $this->http->post($url, ['json'=>[
            'From_Account'=>$formAccount,
            'StartIndex'=>$index,
            'MaxLimited'=>$limit,
            'LastSequence' => $lastSeq
        ]]);
    }

    /**
     * 生成URL链接
     * @param $url string 请求链接
     * @param $user_id mixed|string 用户ID
     * @return string
     * @throws \Exception
     */
    private function getUrlParameter(string $url, string $user_id = null): string
    {
        $identifier = empty($user_id) ? $this->identifier: $user_id;
        $param = http_build_query([
            'sdkappid' => $this->config->accessKeyId,
            'identifier' => $identifier,
            'usersig' => $this->genUserSign($identifier),
            'random' => Str::randomInt(32),
            'contenttype' => 'json'
        ]);
        return $url.$param;
    }

    /**
     * 生成用户签名
     * @param $user_id string 用户ID
     * @return string
     * @throws \Exception
     */
    public function genUserSign(string $user_id)
    {
        return $this->TLSSignAPI->genUserSig($user_id);
    }

    /**
     * @return string
     */
    public function getIdentifier(): string
    {
        return $this->identifier;
    }

    /**
     * @param string $identifier
     */
    public function setIdentifier(string $identifier): Client
    {
        $this->identifier = $identifier;
        return $this;
    }

    /**
     * @return mixed
     */
    public function getAppid()
    {
        return $this->appid;
    }

    /**
     * @param mixed $appid
     */
    public function setAppid($appid): Client
    {
        $this->appid = $appid;
        return $this;
    }

    /**
     * @return mixed
     */
    public function getSecret()
    {
        return $this->secret;
    }

    /**
     * @param mixed $secret
     */
    public function setSecret($secret): Client
    {
        $this->secret = $secret;
        return $this;
    }

}